/*
 * TcpSocket.h
 *
 *  Created on: 2009-8-20
 *      Author: fanliangliang
 */

#ifndef TCP_SOCKET_H_
#define TCP_SOCKET_H_

#include <in_sock.h>
#include "SocketListener.h"
#include "TimeoutListener.h"

class CTcpReader;
class CTcpWriter;
class CTimeoutTimer;

class CTcpSocket : public CActive, public MSocketListener, public MTimeoutListener {
public:
	static CTcpSocket* NewL(MSocketListener& aListener);
	static CTcpSocket* NewLC(MSocketListener& aListener);
	virtual ~CTcpSocket();
	
	void ConnectL(const TDesC& aServerName, TUint aPort);
	void ConnectL(TUint32 aAddress, TUint aPort);
	void Close();
	
	TBool IsConnected() const;
	TSocketState State() const;
	
	void Read();
	void Write(const TDesC8& aBuffer);
	
	const TInetAddr& RemoteName() const;
	const TInetAddr& LocalName() const;
	
	const TDesC& RemoteAddress() const;
	const TDesC& LocalAddress() const;
	
	TInt RemotePort() const;
	TInt LocalPort() const;
	
	void SetTimeout(TTimeoutType aType, TTimeIntervalSeconds aTimeout);
	TTimeIntervalSeconds Timeout(TTimeoutType aType) const;

protected:
	// from CActive
	virtual void DoCancel();
	virtual void RunL();
	
	// from MSocketListener
	virtual void OnResolved();
	virtual void OnConnected();
	virtual void OnDisconnected();
	virtual void OnReceived(const TDesC8& aBuffer);
	virtual void OnStateChanged(TSocketState aState);
	virtual void OnSocketError(TSocketError aError);
	
	// from MTimeoutListener
	virtual void OnTimerExpired();
	
private:
	CTcpSocket(MSocketListener& aListener);
	void ConstuctL();
	void ConnectL();
	void CancelAll();
	void SynClose();
	void AsynClose();
	void InvalidateAddressCache();
	void SetState(TSocketState aState);
	
private:
	RSocket iSocket;
	RSocketServ iSocketServ;
	RHostResolver iResolver;
	TNameEntry iNameEntry;
	TInetAddr iRemoteAddr;
	TInetAddr iLocalAddr;
	
	MSocketListener& iListener;
	CTcpReader* iTcpReader;
	CTcpWriter* iTcpWriter;
	/*
	 * Timer
	 */
	CTimeoutTimer* iTimer;
	
	/*
	 * Timeout for asynchronous host name resolve operation.
	 */
	TTimeIntervalSeconds iResolveTimeout;
	
	/*
	 * Timeout for asynchronous connect operation.
	 */
	TTimeIntervalSeconds iConnectTimeout;
	
	/*
	 * Previous socket state.
	 */
	TSocketState iPreviousState;
	
	/*
	 * Current socket state.
	 */
	TSocketState iCurrentState;
	
	/*
	 * The max length of IPv4 address.
	 */
	enum { KMaxIpv4AddressLength = 15 };
	
	mutable HBufC* iRemoteAddressCache;
	mutable HBufC* iLocalAddressCache;
};

#endif /* TCP_SOCKET_H_ */
